﻿using System;
using System.Web;

using System.Drawing;
using System.Text;


namespace IFD2
{
    public class barcode : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            string source;
            int height, unit_width;
            bool vertical;
            if (context.Request.QueryString["source"] != null)
                source = context.Request.QueryString["source"].ToString();
            else
            {
                //source = "ABCD";
                return;
            }
            if (source.Length == 0)//cause Session clear!!
            {
                //return;//不行！
            }
            if (context.Request.QueryString["height"] != null)
                height = Convert.ToInt16(context.Request.QueryString["height"].ToString());
            else
                height = 60;

            if (context.Request.QueryString["unit_width"] != null)
                unit_width = Convert.ToInt16(context.Request.QueryString["unit_width"].ToString());
            else
                unit_width = 1;

            if (context.Request.QueryString["vertical"] == null)
                vertical = false;
            else if (context.Request.QueryString["vertical"].ToString() == "T")
                vertical = true;
            else
                vertical = false;


            source = bar_code128A(source);
            byte[] data;
            if (!vertical)
                data = GenerateBarCode(source, height, unit_width);
            else
                data = GenerateBarCode_vertical(source, height, unit_width);

            //context.Response.ContentType = "image/png";
            context.Response.OutputStream.Write(data, 0, data.Length);
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public byte[] GenerateBarCode(string source, int height, int unit_width)
        {
            /// <summary>
            /// 生成条码图片
            /// </summary>

            int nBmpWidth = unit_width * source.Length + 2 * 20;//前导空白20；结尾空白20；
            int nBmpHeight = height;
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nBmpWidth, nBmpHeight);

            System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
            graph.FillRectangle(new SolidBrush(System.Drawing.Color.FromArgb(255, 255, 255))
                , 0
                , 0
                , nBmpWidth
                , nBmpHeight);


            for (int i = 1; i <= source.Length; i++)
            {
                if (source.Substring(i - 1, 1) == "|")
                {
                    System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(0, 0, 0), unit_width);
                    graph.DrawLine(pen, 20 + (i - 1) * unit_width + 1, 0, 20 + (i - 1) * unit_width + 1, height);
                }

            }

            System.IO.MemoryStream bstream = new System.IO.MemoryStream();
            bmp.Save(bstream, System.Drawing.Imaging.ImageFormat.Jpeg);
            bmp.Dispose();
            graph.Dispose();

            byte[] byteReturn = bstream.ToArray();
            bstream.Close();

            return byteReturn;
        }

        public byte[] GenerateBarCode_vertical(string source, int height, int unit_width)
        {
            /// <summary>
            /// 生成条码图片
            /// </summary>

            int nBmpWidth = unit_width * source.Length + 2 * 20;//前导空白20；结尾空白20；
            int nBmpHeight = height;
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nBmpHeight, nBmpWidth);

            System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
            graph.FillRectangle(new SolidBrush(System.Drawing.Color.FromArgb(255, 255, 255))
                , 0
                , 0
                , nBmpHeight
                , nBmpWidth);


            for (int i = 1; i <= source.Length; i++)
            {
                if (source.Substring(i - 1, 1) == "|")
                {
                    System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(0, 0, 0), unit_width);
                    graph.DrawLine(pen, 0, 20 + (i - 1) * unit_width + 1, height, 20 + (i - 1) * unit_width + 1);
                }

            }

            System.IO.MemoryStream bstream = new System.IO.MemoryStream();
            bmp.Save(bstream, System.Drawing.Imaging.ImageFormat.Jpeg);
            bmp.Dispose();
            graph.Dispose();

            byte[] byteReturn = bstream.ToArray();
            bstream.Close();

            return byteReturn;
        }
        public string bar_code128A(string source)
        {
            string[] bar128 = new string[106]{
        "||_||__||__",//0
        "||__||_||__",//1
        "||__||__||_",//2
        "|__|__||___",//3
        "|__|___||__",//4
        "|___|__||__",//5
        "|__||__|___",//6
        "|__||___|__",//7
        "|___||__|__",//8
        "||__|__|___",//9
        "||__|___|__",//10
        "||___|__|__",//11
        "|_||__|||__",//12
        "|__||_|||__",//13
        "|__||__|||_",//14
        "|_|||__||__",//15
        "|__|||_||__",//16
        "|__|||__||_",//17
        "||__|||__|_",//18
        "||__|_|||__",//19
        "||__|__|||_",//20
        "||_|||__|__",//21
        "||__|||_|__",//22
        "|||_||_|||_",//23
        "|||_|__||__",//24
        "|||__|_||__",//25
        "|||__|__||_",//26
        "|||_||__|__",//27
        "|||__||_|__",//28
        "|||__||__|_",//29
        "||_||_||___",//30
        "||_||___||_",//31
        "||___||_||_",//32
        "|_|___||___",//33
        "|___|_||___",//34
        "|___|___||_",//35
        "|_||___|___",//36
        "|___||_|___",//37
        "|___||___|_",//38
        "||_|___|___",//39
        "||___|_|___",//40
        "||___|___|_",//41
        "|_||_|||___",//42
        "|_||___|||_",//43
        "|___||_|||_",//44
        "|_|||_||___",//45
        "|_|||___||_",//46
        "|___|||_||_",//47
        "|||_|||_||_",//48
        "||_|___|||_",//49
        "||___|_|||_",//50
        "||_|||_|___",//51
        "||_|||___|_",//52
        "||_|||_|||_",//53
        "|||_|_||___",//54
        "|||_|___||_",//55
        "|||___|_||_",//56
        "|||_||_|___",//57
        "||_||___|_",//58
        "|||___||_|_",//59
        "|||_||||_|_",//60
        "||__|____|_",//61
        "||||___|_|_",//62
        "|_|__||____",//63
        "|_|____||__",//64
        "|__|_||____",//65
        "|__|____||_",//66
        "|____|_||__",//67
        "|____|__||_",//68
        "|_||__|____",//69
        "|_||____|__",//70
        "|__||_|____",//71
        "|__||____|_",//72
        "|____||_|__",//73
        "|____||__|_",//74
        "||____|__|_",//75
        "||__|_|____",//76
        "||||_|||_|_",//77
        "||____|_|__",//78
        "|___||||_|_",//79
        "|_|__||||__",//80
        "|__|_||||__",//81
        "|__|__||||_",//82
        "|_||||__|__",//83
        "|__||||_|__",//84
        "|__||||__|_",//85
        "||||_|__|__",//86
        "||||__|_|__",//87
        "||||__|__|_",//88
        "||_||_||||_",//89
        "||_||||_||_",//90
        "||||_||_||_",//91
        "|_|_||||___",//92
        "|_|___||||_",//93
        "|___|_||||_",//94
        "|_||||_|___",//95
        "|_||||___|_",//96
        "||||_|_|___",//97
        "||||_|___|_",//98
        "|_|||_||||_",//99
        "|_||||_|||_",//100
        "|||_|_||||_",//101
        "||||_|_|||_",//102
        "||_|____|__",//103
        "||_|__|____",//104
        "||_|__|||__"//105
        };
            string strTmp = source;
            StringBuilder target = new StringBuilder();
            int i;
            string code = strTmp;
            string cur;
            int veri_sum;
            // ToLower()将string转化成小写形式的副本，返回是使用指定区域的性的大小写规则。
            strTmp = strTmp.Trim().ToUpper();
            //结构：起始符，数据，校验位；结束符；
            target = target.Append(bar128[103]);//起始符 “A”
            veri_sum = 103;
            for (i = 1; i <= strTmp.Length; i++)
            {
                cur = strTmp.Substring(i - 1, 1);
                switch (cur)
                {
                    case "0":
                        target = target.Append(bar128[16]);
                        veri_sum += 16 * i;
                        break;
                    case "1":
                        target = target.Append(bar128[17]);
                        veri_sum += 17 * i;
                        break;
                    case "2":
                        target = target.Append(bar128[18]);
                        veri_sum += 18 * i;
                        break;
                    case "3":
                        target = target.Append(bar128[19]);
                        veri_sum += 19 * i;
                        break;
                    case "4":
                        target = target.Append(bar128[20]);
                        veri_sum += 20 * i;
                        break;
                    case "5":
                        target = target.Append(bar128[21]);
                        veri_sum += 21 * i;
                        break;
                    case "6":
                        target = target.Append(bar128[22]);
                        veri_sum += 22 * i;
                        break;
                    case "7":
                        target = target.Append(bar128[23]);
                        veri_sum += 23 * i;
                        break;
                    case "8":
                        target = target.Append(bar128[24]);
                        veri_sum += 24 * i;
                        break;
                    case "9":
                        target = target.Append(bar128[25]);
                        veri_sum += 25 * i;
                        break;
                    case "A":
                        target = target.Append(bar128[33]);
                        veri_sum += 33 * i;
                        break;
                    case "B":
                        target = target.Append(bar128[34]);
                        veri_sum += 34 * i;
                        break;
                    case "C":
                        target = target.Append(bar128[35]);
                        veri_sum += 35 * i;
                        break;
                    case "D":
                        target = target.Append(bar128[36]);
                        veri_sum += 36 * i;
                        break;
                    case "E":
                        target = target.Append(bar128[37]);
                        veri_sum += 37 * i;
                        break;
                    case "F":
                        target = target.Append(bar128[38]);
                        veri_sum += 38 * i;
                        break;
                    case "G":
                        target = target.Append(bar128[39]);
                        veri_sum += 39 * i;
                        break;
                    case "H":
                        target = target.Append(bar128[40]);
                        veri_sum += 40 * i;
                        break;
                    case "I":
                        target = target.Append(bar128[41]);
                        veri_sum += 41 * i;
                        break;
                    case "J":
                        target = target.Append(bar128[42]);
                        veri_sum += 42 * i;
                        break;
                    case "K":
                        target = target.Append(bar128[43]);
                        veri_sum += 43 * i;
                        break;
                    case "L":
                        target = target.Append(bar128[44]);
                        veri_sum += 44 * i;
                        break;
                    case "M":
                        target = target.Append(bar128[45]);
                        veri_sum += 45 * i;
                        break;
                    case "N":
                        target = target.Append(bar128[46]);
                        veri_sum += 46 * i;
                        break;
                    case "O":
                        target = target.Append(bar128[47]);
                        veri_sum += 47 * i;
                        break;
                    case "P":
                        target = target.Append(bar128[48]);
                        veri_sum += 48 * i;
                        break;
                    case "Q":
                        target = target.Append(bar128[49]);
                        veri_sum += 49 * i;
                        break;
                    case "R":
                        target = target.Append(bar128[50]);
                        veri_sum += 50 * i;
                        break;
                    case "S":
                        target = target.Append(bar128[51]);
                        veri_sum += 51 * i;
                        break;
                    case "T":
                        target = target.Append(bar128[52]);
                        veri_sum += 52 * i;
                        break;
                    case "U":
                        target = target.Append(bar128[53]);
                        veri_sum += 53 * i;
                        break;
                    case "V":
                        target = target.Append(bar128[54]);
                        veri_sum += 54 * i;
                        break;
                    case "W":
                        target = target.Append(bar128[55]);
                        veri_sum += 55 * i;
                        break;
                    case "X":
                        target = target.Append(bar128[56]);
                        veri_sum += 56 * i;
                        break;
                    case "Y":
                        target = target.Append(bar128[57]);
                        veri_sum += 57 * i;
                        break;
                    case "Z":
                        target = target.Append(bar128[58]);
                        veri_sum += 58 * i;
                        break;
                    case "-":
                        target = target.Append(bar128[13]);
                        veri_sum += 13 * i;
                        break;
                    case "*":
                        target = target.Append(bar128[10]);
                        veri_sum += 10 * i;
                        break;
                    case "/":
                        target = target.Append(bar128[15]);
                        veri_sum += 15 * i;
                        break;
                    case "%":
                        target = target.Append(bar128[5]);
                        veri_sum += 5 * i;
                        break;
                    case "+":
                        target = target.Append(bar128[11]);
                        veri_sum += 11 * i;
                        break;
                    case ".":
                        target = target.Append(bar128[14]);
                        veri_sum += 14 * i;
                        break;
                    //case " "://database space!
                    //    break;
                    default:
                        return "";//invalid character!
                }
            }
            veri_sum = veri_sum % 103;
            target = target.Append(bar128[veri_sum]);//校验符
            target = target.Append("||___|||_|_||");//结束符

            //strTmp = target.ToString().Replace("_", "<span style='height:" + height + ";width:" + width + ";background:#FFFFFF;'></span>");
            //strTmp = strTmp.Replace("|", "<span style='height:" + height + ";width:" + width + ";background:#000000;'></span>");
            //if (type_code == 1)
            //{
            //    return strTmp + "<BR>" + code;
            //}
            //else
            //{
            //    return strTmp;
            //}
            return target.ToString();
        }
        public string bar_code39(string source)
        {
            /*
            CODE39码的编码规则是：
            １、 每五条线表示一个字符；
            ２、 粗线表示１，细线表示０；
            ３、 线条间的间隙宽的表示１，窄的表示０；
            ４、 五条线加上它们之间的四条间隙就是九位二进制编码，而且这九位中必定有三位是1，所以称为39码；
            ５、 条形码的首尾各一个＊标识开始和结束
            注释： "0"-"9","A-Z","-","%","$"和"*" 的条码编码格式,总共 40 个字符 Static strBarTable(39) As String
            注释： 初始化条码编码格式表
            strBarTable(0) = "001100100"　　 注释： 0
            strBarTable(1) = "100010100"　　 注释： 1
            strBarTable(2) = "010010100"　　 注释： 2
            strBarTable(3) = "110000100"　　 注释： 3
            strBarTable(4) = "001010100"　　 注释： 4
            strBarTable(5) = "101000100"　　 注释： 5
            strBarTable(6) = "011000100"　　 注释： 6
            strBarTable(7) = "000110100"　　 注释： 7
            strBarTable(8) = "100100100"　　 注释： 8
            strBarTable(9) = "010100100"　　 注释： 9
            strBarTable(10) = "100010010"　　注释： A
            strBarTable(11) = "010010010"　　注释： B
            strBarTable(12) = "110000010"　　注释： C
            strBarTable(13) = "001010010"　　注释： D
            strBarTable(14) = "101000010"　　注释： E
            strBarTable(15) = "011000010"　　注释： F
            strBarTable(16) = "000110010"　　注释： G
            strBarTable(17) = "100100010"　　注释： H
            strBarTable(18) = "010100010"　　注释： I
            strBarTable(19) = "001100010"　　注释： J
            strBarTable(20) = "100010001"　　注释： K
            strBarTable(21) = "010010001"　　注释： L
            strBarTable(22) = "110000001"　　注释： M
            strBarTable(23) = "001010001"　　注释： N
            strBarTable(24) = "101000001"　　注释： O
            strBarTable(25) = "011000001"　　注释： P
            strBarTable(26) = "000110001"　　注释： Q
            strBarTable(27) = "100100001"　　注释： R
            strBarTable(28) = "010100001"　　注释： S
            strBarTable(29) = "001100001"　　注释： T
            strBarTable(30) = "100011000"　　注释： U
            strBarTable(31) = "010011000"　　注释： V
            strBarTable(32) = "110001000"　　注释： W
            strBarTable(33) = "001011000"　　注释： X
            strBarTable(34) = "101001000"　　注释： Y
            strBarTable(35) = "011001000"　　注释： Z
            strBarTable(36) = "000111000"　　注释： -
            strBarTable(37) = "100101000"　　注释： %
            strBarTable(38) = "010101000"　　注释： $
            strBarTable(39) = "001101000"　　注释： *
                */
            //str:输入的字符串;ch:要显示条形码的高度;cw:要显示条形码的宽度;type_code:代码类型
            string strTmp;
            //string code = strTmp;
            strTmp = "*" + source.Trim() + "*";
            // ToLower()将string转化成小写形式的副本，返回是使用指定区域的性的大小写规则。
            strTmp = strTmp.ToUpper();
            //int height = ch;
            //int width = cw;
            //StringBuilder final = new StringBuilder(); ;

            //将传入的参数进行转化。
            strTmp = strTmp.Replace("0", "_|_|__||_||_|"); ;
            strTmp = strTmp.Replace("1", "_||_|__|_|_||");
            strTmp = strTmp.Replace("2", "_|_||__|_|_||");
            strTmp = strTmp.Replace("3", "_||_||__|_|_|");
            strTmp = strTmp.Replace("4", "_|_|__||_|_||");
            strTmp = strTmp.Replace("5", "_||_|__||_|_|");
            strTmp = strTmp.Replace("7", "_|_|__|_||_||");
            strTmp = strTmp.Replace("6", "_|_||__||_|_|");
            strTmp = strTmp.Replace("8", "_||_|__|_||_|");
            strTmp = strTmp.Replace("9", "_|_||__|_||_|");
            strTmp = strTmp.Replace("A", "_||_|_|__|_||");
            strTmp = strTmp.Replace("B", "_|_||_|__|_||");
            strTmp = strTmp.Replace("C", "_||_||_|__|_|");
            strTmp = strTmp.Replace("D", "_|_|_||__|_||");
            strTmp = strTmp.Replace("E", "_||_|_||__|_|");
            strTmp = strTmp.Replace("F", "_|_||_||__|_|");
            strTmp = strTmp.Replace("G", "_|_|_|__||_||");
            strTmp = strTmp.Replace("H", "_||_|_|__||_|");
            strTmp = strTmp.Replace("I", "_|_||_|__||_|");
            strTmp = strTmp.Replace("J", "_|_|_||__||_|");
            strTmp = strTmp.Replace("K", "_||_|_|_|__||");
            strTmp = strTmp.Replace("L", "_|_||_|_|__||");
            strTmp = strTmp.Replace("M", "_||_||_|_|__|");
            strTmp = strTmp.Replace("N", "_|_|_||_|__||");
            strTmp = strTmp.Replace("O", "_||_|_||_|__|");
            strTmp = strTmp.Replace("P", "_|_||_||_|__|");
            strTmp = strTmp.Replace("R", "_||_|_|_||__|");
            strTmp = strTmp.Replace("Q", "_|_|_|_||__||");
            strTmp = strTmp.Replace("S", "_|_||_|_||__|");
            strTmp = strTmp.Replace("T", "_|_|_||_||__|");
            strTmp = strTmp.Replace("U", "_||__|_|_|_||");
            strTmp = strTmp.Replace("V", "_|__||_|_|_||");
            strTmp = strTmp.Replace("W", "_||__||_|_|_|");
            strTmp = strTmp.Replace("X", "_|__|_||_|_||");
            strTmp = strTmp.Replace("Y", "_||__|_||_|_|");
            strTmp = strTmp.Replace("Z", "_|__||_||_|_|");
            strTmp = strTmp.Replace("-", "_|__|_|_||_||");
            strTmp = strTmp.Replace("*", "_|__|_||_||_|");
            strTmp = strTmp.Replace("/", "_|__|__|_|__|");
            strTmp = strTmp.Replace("%", "_|_|__|__|__|");
            strTmp = strTmp.Replace("+", "_|__|_|__|__|");
            strTmp = strTmp.Replace(".", "_||__|_|_||_|");
            //strTmp = strTmp.Replace("_", "<span style='height:" + height + ";width:" + width + ";background:#FFFFFF;'></span>");
            //strTmp = strTmp.Replace("|", "<span style='height:" + height + ";width:" + width + ";background:#000000;'></span>");
            //final=final.Append("<span style='height:" + height + ";width:20;background:#FFFFFF;'></span>");
            //final = final.Append(strTmp);
            //final = final.Append("<span style='height:" + height + ";width:20;background:#FFFFFF;'></span>");
            //if (type_code == 1)
            //{
            //    return /*final.ToString()*/strTmp + "<BR>" + code;
            //}
            //else
            //{
            //    return /*final.ToString();*/ strTmp;
            //}

            return /*final.ToString();*/ strTmp;
        }
    }
}